package com.tabbinder.server;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Binder {
	@NotPersistent
	private static Logger log = Logger.getLogger(Binder.class.getName());

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Long id;

	@Persistent
	private String title;

	/** Unordered collection of bind records */
	@Persistent(mappedBy = "binder")
	private Set<BindRecord> records = new HashSet<BindRecord>();

	/** ordered collection of Links */
	@Persistent
	private List<LinkRecord> links = new ArrayList<LinkRecord>();

	public Binder(String title) {
		this.title = title;
	}

	public Binder(JSONObject item) throws JSONException {
		// Set id only if it is not -1
		long nid = item.getLong("id");
		if (nid != -1)
			this.id = nid;

		this.title = item.getString("title");
		JSONArray array = null;
		try {
			array = item.getJSONArray("links");
		} catch (JSONException ex) {
		}
		if (array != null)
			setLinksFrom(array);
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Long getId() {
		return id;
	}

	@Override
	public String toString() {
		return id + ": " + title + "; " + links.size() + " links and "
				+ records.size() + " records";
	}

	/** Return a new JSON object for this instance */
	public JSONObject toJson() {
		JSONObject res = new JSONObject();
		try {
			res.put("id", id);
			res.put("title", title);
			res.put("record_count", records.size());

			JSONArray lnks = new JSONArray();
			if (links != null)
				for (LinkRecord l : links) {
					lnks.put(l.toJson());
				}
			res.put("links", lnks);
		} catch (JSONException e) {
			log.log(Level.SEVERE, "Cannot create JSON: ", e);
			return null;
		}
		return res;
	}

	public void addRecord(BindRecord record) {
		this.records.add(record);
	}

	public Set<BindRecord> getRecords() {
		return records;
	}

	public void addLink(LinkRecord link) {
		this.links.add(link);
	}

	public void setLinksFrom(JSONArray array) throws JSONException {
		if (links == null)
			links = new ArrayList<LinkRecord>();
		else
			links.clear();
		if (array == null)
			return;
		for (int i = 0; i < array.length(); i++)
			if (!array.isNull(i)) {
				JSONObject json = array.getJSONObject(i);
				links.add(new LinkRecord(json));
			}
	}

	public List<LinkRecord> getLinks() {
		return links;
	}
}
